from flask import Blueprint, request, jsonify, g
from datetime import datetime, timedelta

from app.models.agents import ActivationCode, Agent
from app.models.user import User
from app.models.cardRecord import CardRecord
from app.core.extensions import db
from sqlalchemy import func, and_, or_, desc

from app.services.decorators import admin_required

# 创建蓝图
dashboard_bp = Blueprint('admin_dashboard', __name__)


@dashboard_bp.route('/stats', methods=['GET'])
def get_dashboard_stats():
    """
    获取代理管理系统仪表盘统计数据
    ---
    参数:
      - agent_id: 代理ID
      - period: 统计周期(day/week/month/year)，默认month
    返回:
      - code: 0表示成功
      - data:
        - code_stats: 卡密统计数据
          - today_used: 今日销售数量
          - yesterday_used: 昨日销售数量
          - month_used: 本月销售数量
          - last_month_used: 上月销售数量
          - total_used: 总销售数量
          - month_generated: 本月生成数量
          - last_month_generated: 上月生成数量
          - stock_remaining: 库存余量
        - team_stats: 团队统计数据
          - team_size: 团队规模
          - team_month_sales: 团队本月销售
          - team_total_sales: 团队总销售
    """
    # 从请求参数获取代理ID
    agent_id = request.args.get('agent_id')

    if not agent_id:
        return jsonify({"code": 1, "message": "缺少代理ID参数"})

    try:
        # 获取时间节点
        now = datetime.now()
        today_start = datetime(now.year, now.month, now.day)
        yesterday_start = today_start - timedelta(days=1)
        yesterday_end = today_start

        # 获取本月和上月的起止时间
        this_month_start = datetime(now.year, now.month, 1)
        if now.month == 1:
            last_month_start = datetime(now.year - 1, 12, 1)
            last_month_end = datetime(now.year, 1, 1)
        else:
            last_month_start = datetime(now.year, now.month - 1, 1)
            last_month_end = this_month_start

        # 初始化统计数据
        code_stats = {
            "today_used": 0,  # 今日销售（已使用的卡密）
            "yesterday_used": 0,  # 昨日销售
            "month_used": 0,  # 本月销售
            "last_month_used": 0,  # 上月销售
            "total_used": 0,  # 累计销售
            "month_generated": 0,  # 本月拿码（生成的激活码）
            "last_month_generated": 0,  # 上月拿码
            "stock_remaining": 0,  # 剩余库存
        }

        team_stats = {
            "team_size": 0,  # 团队规模
            "team_month_sales": 0,  # 团队本月销售
            "team_total_sales": 0,  # 团队总销售
        }

        # 获取代理信息
        agent = Agent.query.get(agent_id)
        if not agent:
            return jsonify({"code": 1, "message": "代理不存在"})

        # 计算今日销售 - 使用status=1表示已售卖/已使用
        today_used = db.session.query(func.count(ActivationCode.id)).filter(
            ActivationCode.created_by == agent_id,
            ActivationCode.status == 1,  # 已使用/已售卖
            ActivationCode.used_time >= today_start
        ).scalar() or 0
        code_stats["today_used"] = today_used

        # 计算昨日销售
        yesterday_used = db.session.query(func.count(ActivationCode.id)).filter(
            ActivationCode.created_by == agent_id,
            ActivationCode.status == 1,  # 已使用/已售卖
            ActivationCode.used_time >= yesterday_start,
            ActivationCode.used_time < yesterday_end
        ).scalar() or 0
        code_stats["yesterday_used"] = yesterday_used

        # 计算本月销售
        month_used = db.session.query(func.count(ActivationCode.id)).filter(
            ActivationCode.created_by == agent_id,
            ActivationCode.status == 1,  # 已使用/已售卖
            ActivationCode.used_time >= this_month_start
        ).scalar() or 0
        code_stats["month_used"] = month_used

        # 计算上月销售
        last_month_used = db.session.query(func.count(ActivationCode.id)).filter(
            ActivationCode.created_by == agent_id,
            ActivationCode.status == 1,  # 已使用/已售卖
            ActivationCode.used_time >= last_month_start,
            ActivationCode.used_time < last_month_end
        ).scalar() or 0
        code_stats["last_month_used"] = last_month_used

        # 计算累计销售
        total_used = db.session.query(func.count(ActivationCode.id)).filter(
            ActivationCode.created_by == agent_id,
            ActivationCode.status == 1  # 已使用/已售卖
        ).scalar() or 0
        code_stats["total_used"] = total_used

        # 计算本月生成的激活码数量
        month_generated = db.session.query(func.count(ActivationCode.id)).filter(
            ActivationCode.created_by == agent_id,
            ActivationCode.create_time >= this_month_start
        ).scalar() or 0
        code_stats["month_generated"] = month_generated

        # 计算上月生成的激活码数量
        last_month_generated = db.session.query(func.count(ActivationCode.id)).filter(
            ActivationCode.created_by == agent_id,
            ActivationCode.create_time >= last_month_start,
            ActivationCode.create_time < last_month_end
        ).scalar() or 0
        code_stats["last_month_generated"] = last_month_generated

        # 计算剩余库存（未使用的激活码数量）
        stock_remaining = db.session.query(func.count(ActivationCode.id)).filter(
            ActivationCode.created_by == agent_id,
            ActivationCode.status == 0  # 未使用/未售卖
        ).scalar() or 0
        code_stats["stock_remaining"] = stock_remaining

        # 获取本月1号
        first_day_this_month = datetime(now.year, now.month, 1)

        # 获取上月1号
        first_day_last_month = (first_day_this_month - timedelta(days=1)).replace(day=1)

        # 获取上月最后一天
        last_day_last_month = first_day_this_month - timedelta(seconds=1)

        # 上月未使用激活码数量（上月拿码）
        stock_last_month = db.session.query(func.count(ActivationCode.id)).filter(
            ActivationCode.created_by == agent_id,
            ActivationCode.status == 0,  # 未使用
            ActivationCode.create_time >= first_day_last_month,
            ActivationCode.create_time <= last_day_last_month
        ).scalar() or 0

        # 本月未使用激活码数量（本月拿码）
        stock_this_month = db.session.query(func.count(ActivationCode.id)).filter(
            ActivationCode.created_by == agent_id,
            ActivationCode.status == 0,  # 未使用
            ActivationCode.create_time >= first_day_this_month
        ).scalar() or 0

        # 保存到统计结果
        code_stats["stock_last_month"] = stock_last_month
        code_stats["stock_this_month"] = stock_this_month

        # 统计本月开卡次数
        now = datetime.now()
        month_start = datetime(now.year, now.month, 1)
        month_count = db.session.query(func.sum(CardRecord.count)).filter(
            CardRecord.user_id == agent_id,
            CardRecord.created_at >= month_start
        ).scalar() or 0
        # 统计上月开卡次数
        if now.month == 1:
            last_month_start = datetime(now.year - 1, 12, 1)
            last_month_end = datetime(now.year, 1, 1)
        else:
            last_month_start = datetime(now.year, now.month - 1, 1)
            last_month_end = month_start

        last_month_count = db.session.query(func.sum(CardRecord.count)).filter(
            CardRecord.user_id == agent_id,
            CardRecord.created_at >= last_month_start,
            CardRecord.created_at < last_month_end
        ).scalar() or 0

        # 保存到统计结果
        code_stats["month_count"] = month_count
        code_stats["last_month_count"] = last_month_count

        # 团队统计
        # 如果有团队成员
        if agent:
            # 获取所有下级代理ID
            team_members = agent.get_all_children()
            team_stats["team_size"] = len(team_members)

            if team_members:
                # 获取团队成员IDs
                team_member_ids = [member.id for member in team_members]
                team_member_ids.append(int(agent_id))  # 包含自己

                # 团队本月销售
                team_month_sales = db.session.query(func.count(ActivationCode.id)).filter(
                    ActivationCode.created_by.in_(team_member_ids),
                    ActivationCode.status == 1,  # 已使用/已售卖
                    ActivationCode.used_time >= this_month_start
                ).scalar() or 0
                team_stats["team_month_sales"] = team_month_sales

                # 团队总销售
                team_total_sales = db.session.query(func.count(ActivationCode.id)).filter(
                    ActivationCode.created_by.in_(team_member_ids),
                    ActivationCode.status == 1  # 已使用/已售卖
                ).scalar() or 0
                team_stats["team_total_sales"] = team_total_sales

        # 构建返回数据
        result = {
            "code_stats": code_stats,
            "team_stats": team_stats
        }

        return jsonify({"code": 0, "data": result})

    except Exception as e:
        print(f"获取代理仪表盘统计数据失败: {str(e)}")
        return jsonify({"code": 500, "message": f"获取统计数据失败: {str(e)}"}), 500


@dashboard_bp.route('/today-stats', methods=['GET'])
def get_dashboard():
    """
    获取代理管理系统仪表盘统计数据
    ---
    参数:
      - tenant_id: 租户ID（必传）
      - agent_id: 代理ID
      - period: 统计周期(day/week/month/year)，默认month
    返回:
      - code: 0表示成功
      - data:
        - code_stats: 卡密统计数据
          - today_used: 今日销售数量
          - yesterday_used: 昨日销售数量
          - month_used: 本月销售数量
          - last_month_used: 上月销售数量
          - total_used: 总销售数量
          - month_generated: 本月生成数量
          - last_month_generated: 上月生成数量
          - stock_remaining: 库存余量
        - team_stats: 团队统计数据
          - team_size: 团队规模
          - team_month_sales: 团队本月销售
          - team_total_sales: 团队总销售
    """

    try:
        # 获取租户ID参数
        tenant_id = request.args.get('tenant_id', type=int)
        if not tenant_id:
            return jsonify({"code": 400, "message": "租户ID不能为空"}), 400
        # 获取时间节点
        now = datetime.now()
        today_start = datetime(now.year, now.month, now.day)
        yesterday_start = today_start - timedelta(days=1)
        yesterday_end = today_start

        # 获取本月和上月的起止时间
        this_month_start = datetime(now.year, now.month, 1)
        if now.month == 1:
            last_month_start = datetime(now.year - 1, 12, 1)
            last_month_end = datetime(now.year, 1, 1)
        else:
            last_month_start = datetime(now.year, now.month - 1, 1)
            last_month_end = this_month_start

        # 初始化统计数据
        code_stats = {
            "today_used": 0,  # 今日销售（已使用的卡密）
            "yesterday_used": 0,  # 昨日销售
            "month_used": 0,  # 本月销售
            "last_month_used": 0,  # 上月销售
            "total_used": 0,  # 累计销售
            "today_new_users": 0,  # 今日新增用户
            "month_new_users": 0,  # 本月新增用户
        }

        # 计算今日销售 - 使用status=1表示已售卖/已使用（手动添加租户过滤）
        today_used = db.session.query(func.count(ActivationCode.id)).filter(
            ActivationCode.tenant_id == tenant_id,  # 手动租户过滤
            ActivationCode.status == 1,  # 已使用/已售卖
            ActivationCode.used_time >= today_start
        ).scalar() or 0
        code_stats["today_used"] = today_used

        # 计算昨日销售（手动添加租户过滤）
        yesterday_used = db.session.query(func.count(ActivationCode.id)).filter(
            ActivationCode.tenant_id == tenant_id,  # 手动租户过滤
            ActivationCode.status == 1,  # 已使用/已售卖
            ActivationCode.used_time >= yesterday_start,
            ActivationCode.used_time < yesterday_end
        ).scalar() or 0
        code_stats["yesterday_used"] = yesterday_used

        # 计算本月销售（手动添加租户过滤）
        month_used = db.session.query(func.count(ActivationCode.id)).filter(
            ActivationCode.tenant_id == tenant_id,  # 手动租户过滤
            ActivationCode.status == 1,  # 已使用/已售卖
            ActivationCode.used_time >= this_month_start
        ).scalar() or 0
        code_stats["month_used"] = month_used

        # 计算上月销售（手动添加租户过滤）
        last_month_used = db.session.query(func.count(ActivationCode.id)).filter(
            ActivationCode.tenant_id == tenant_id,  # 手动租户过滤
            ActivationCode.status == 1,  # 已使用/已售卖
            ActivationCode.used_time >= last_month_start,
            ActivationCode.used_time < last_month_end
        ).scalar() or 0
        code_stats["last_month_used"] = last_month_used

        # 计算累计销售（手动添加租户过滤）
        total_used = db.session.query(func.count(ActivationCode.id)).filter(
            ActivationCode.tenant_id == tenant_id,  # 手动租户过滤
            ActivationCode.status == 1  # 已使用/已售卖
        ).scalar() or 0
        code_stats["total_used"] = total_used

        # === 用户数据统计（手动添加租户过滤） ===
        today_new_users = db.session.query(func.count(User.user_id)).filter(
            User.tenant_id == tenant_id,  # 手动租户过滤
            User.create_time >= today_start
        ).scalar() or 0

        month_new_users = db.session.query(func.count(User.user_id)).filter(
            User.tenant_id == tenant_id,  # 手动租户过滤
            User.create_time >= this_month_start
        ).scalar() or 0

        code_stats["today_new_users"] = today_new_users
        code_stats["month_new_users"] = month_new_users
        # 构建返回数据
        result = {
            "code_stats": code_stats,
        }

        return jsonify({"code": 0, "data": result})

    except Exception as e:
        print(f"获取代理仪表盘统计数据失败: {str(e)}")
        return jsonify({"code": 500, "message": f"获取统计数据失败: {str(e)}"}), 500


# 注册蓝图
def init_app(app):
    app.register_blueprint(dashboard_bp, url_prefix='/api/admin/mp/dashboard')
